var private const	Select_pos = 1;
var private 	select_string = "選択";

function SelectTypeALL()
{
	AreaMode = SELECT_ALL;
	Status_title[Select_pos] = "指定範囲内の面を"+select_string;
	DrawStatus();
}

function SelectTypeSUB()
{
	AreaMode = SELECT_SUB;
	Status_title[Select_pos] = "指定範囲を含む面を"+select_string;
	DrawStatus();
}

//
//	選択（および非選択）
//	flag	:	Select の flag
//
function	SelectAreaFor3D( flag )
{
	var	i, key, win_type ;
	var	cur1, cur0 ;
	var	pos1[3], pos0[3], logical ;
	var	pick, draw_flag = ON;

	cur0 = Cursor();
	cur1 = cur0;
	pick = cur0;
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
			DrawBox( cur0, cur1 );
		key = WaitEvent();
		if( key )
			input_flag = ON;
		cur1 = Cursor();
		key = KeyCode();
		if ( input_flag | key == INPUT_KEY )
		{
			Clear( OVERWRITE );
			break;
		}
		else if ( key == ESC | key == BS | quit_flag == TRUE )
		{
			Warning();
			Clear( OVERWRITE );
			return;
		}
		else if( key == 'c' )
		{
			if( AreaMode == SELECT_ALL )
				SelectTypeSUB();
			else
				SelectTypeALL();
		}
		else
			KeyProcess( key );
		if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
		{
			draw_flag = ON;
			DrawBox( pick, cur0 );
		}
		else
			draw_flag = OFF;
		pick = Cursor();
		input_flag = OFF;
	}

	if( flag == TRUE )
	{
		if (( ShiftStat() & 3 ) == 1 )
			logical = SELECT_OR;
		else if (( ShiftStat() & 3 ) == 2 )
		{
			flag = FALSE;
			logical = SELECT_AND;
		}
		else if (( ShiftStat() & 3 ) == 3 )
		{
			flag = FALSE;
			logical = SELECT_AND;
		}
		else
			logical = SELECT_UPDATE;
	}
	else
	{
		if(( ShiftStat() & 3 ) == 2 )
		{
			flag = TRUE;
			logical = SELECT_UPDATE;
		}
		else if(( ShiftStat() & 3 ) == 3 )
		{
			flag = TRUE;
			logical = SELECT_OR;
		}
		else
			logical = SELECT_AND;
	}

	if ( cur0 == cur1 )
	{
		cur0 = PolyVertex( cur0 );
		SelectArea( flag, logical|AreaMode, cur0, cur0 );
	}
	else
	{
		Position( cur0, pos0 );
		Position( cur1, pos1 );
		win_type = MouseWindow();
		if( win_type == WIN_XY )
			i = 2;
		else if( win_type == WIN_YZ )
			i = 0;
		else
			i = 1;
		if( pos0[i] == pos1[i] )
		{
			pos0[i] = VERTEX_MIN;
			pos1[i] = VERTEX_MAX;
		}
		SelectArea( flag, logical|AreaMode,
			Vertex( pos0[0], pos0[1], pos0[2] ),
			Vertex( pos1[0], pos1[1], pos1[2] ) );
	}
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

function	SelectAreaForPers( flag )
{
	var	key, logical ;
	var	cur0_pos, cur1_pos, cur0[2], cur1[2] ;

	cur0_pos = Cursor();
	Cursor2D( cur0 );
	cur1 = cur0;
	input_flag = OFF;
	while( TRUE )
	{
		DrawBox2D( cur0[0], cur0[1], cur1[0], cur1[1] );
		key = WaitEvent();
		if( key )
			input_flag = ON;
		DrawBox2D( cur0[0], cur0[1], cur1[0], cur1[1] );
		Cursor2D( cur1 );
		key = KeyCode();
		if ( input_flag | key == INPUT_KEY )
			break;
		else if ( key == ESC | key == BS | quit_flag == TRUE )
		{
			Warning();
			Clear( OVERWRITE );
			return;
		}
		else if( key == 'c' )
		{
			if( AreaMode == SELECT_ALL )
				SelectTypeSUB();
			else
				SelectTypeALL();
		}
		else
			KeyProcess( key );
	}
	cur1_pos = Cursor();

	if( flag == TRUE )
	{
		if (( ShiftStat() & 3 ) == 1 )
			logical = SELECT_OR;
		else if (( ShiftStat() & 3 ) == 2 )
		{
			flag = FALSE;
			logical = SELECT_AND;
		}
		else if (( ShiftStat() & 3 ) == 3 )
		{
			flag = FALSE;
			logical = SELECT_AND;
		}
		else
			logical = SELECT_UPDATE;
	}
	else
	{
		if(( ShiftStat() & 3 ) == 2 )
		{
			flag = TRUE;
			logical = SELECT_UPDATE;
		}
		else if(( ShiftStat() & 3 ) == 3 )
		{
			flag = TRUE;
			logical = SELECT_OR;
		}
		else
			logical = SELECT_AND;
	}

	SelectPers( flag, logical|AreaMode, cur0[0], cur0[1], cur1[0], cur1[1] );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

function	AreaSelect()
{
	var	mode ;

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"一部を選択",		SelectTypeSUB,
			"全体を選択",		SelectTypeALL,
			"----------",		SEPARATE_MENU,
			"指定中止  	ESC",	MenuQuit
		), Menu_Title );

	ClearStatus();
	Status_title[0] = "【選択範囲指定中】";
	select_string = "選択";
	if( AreaMode == SELECT_ALL )
		SelectTypeALL();
	else
		SelectTypeSUB();

	quit_flag = FALSE;
	if ( MouseWindow() == WIN_PERS )
		SelectAreaForPers( TRUE );
	else
		SelectAreaFor3D( TRUE );
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
	prevnext_flag = FALSE;
}

function	AreaDeselect()
{
	PushMenu();
	Status_org = Status_title;

	MenuPosition( Menu( " 動作設定(&S)",
			"一部を選択",		SelectTypeSUB,
			"全体を選択",		SelectTypeALL,
			"----------",		SEPARATE_MENU,
			"指定中止  	ESC",	MenuQuit
		), Menu_Title );

	ClearStatus();
	Status_title[0] = "【非選択範囲指定中】";
	select_string = "非選択";
	if( AreaMode == SELECT_ALL )
		SelectTypeALL();
	else
		SelectTypeSUB();

	quit_flag = FALSE;
	if ( MouseWindow() == WIN_PERS )
		SelectAreaForPers( FALSE );
	else
		SelectAreaFor3D( FALSE );
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
	prevnext_flag = FALSE;
}

//
//	全てを選択
//
function _SelectAll()
{
	var	mode;

	if ( ShiftStat() & 2 )
		mode = SELECT_XOR;
	else
		mode = SELECT_UPDATE;
	SelectAll( TRUE, mode );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	全てを非選択
//
function DeselectAll()
{
	SelectAllFalse();
	SelectAll( FALSE );
	prevnext_flag = FALSE;
}

//
//	選択範囲を反転
//
function SelectInv()
{
	SelectAll( TRUE, SELECT_XOR );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	カレントアトリビュートを選択
//
function _SelectAtr()
{
	if (( ShiftStat() & 3 ) == 1 )
		SelectAttr( AttrCurrent(), TRUE, SELECT_OR );
	else if (( ShiftStat() & 3 ) == 2 )
		SelectAttr( AttrCurrent(), TRUE, SELECT_AND );
	else if (( ShiftStat() & 3 ) == 3 )
		SelectAttr( AttrCurrent(), TRUE, SELECT_XOR );
	else
		SelectAttr( AttrCurrent(), TRUE, SELECT_UPDATE );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	カレントアトリビュートを非選択
//
function DeselectAtr()
{
	SelectAttr( AttrCurrent(), FALSE, SELECT_AND );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	カレントオブジェクトを選択
//
function _SelectObj()
{
	if (( ShiftStat() & 3 ) == 1 )
		SelectObj( ObjCurrent(), TRUE, SELECT_OR );
	else if (( ShiftStat() & 3 ) == 2 )
		SelectObj( ObjCurrent(), TRUE, SELECT_AND );
	else if (( ShiftStat() & 3 ) == 3 )
		SelectObj( ObjCurrent(), TRUE, SELECT_XOR );
	else
		SelectObj( ObjCurrent(), TRUE, SELECT_UPDATE );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	カレントオブジェクトを非選択
//
function DeselectObj()
{
	SelectObj( ObjCurrent(), FALSE, SELECT_AND );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	シェーディングされた面を選択
//
function SelectShade()
{
	var	sel1, sel2;

	sel1 = Select();
	SelectPolyType( POLY_SHADE, TRUE, SELECT_UPDATE );
	SelectPolyType( POLY_UVSHADE, TRUE, SELECT_OR );
	sel2 = Select();
	if (( ShiftStat() & 3 ) == 1 )
		Select(sel1|sel2);
	else if (( ShiftStat() & 3 ) == 2 )
		Select(sel1&sel2);
	else if (( ShiftStat() & 3 ) == 3 )
		Select(sel1^sel2);
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	シェーディングされた面を非選択
//
function DeselectShade()
{
	SelectPolyType( POLY_SHADE, FALSE, SELECT_AND );
	SelectPolyType( POLY_UVSHADE, FALSE, SELECT_AND );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	マッピングされた面を選択
//
function SelectMap()
{
	var	sel1, sel2;

	sel1 = Select();
	SelectPolyType( POLY_UV, TRUE, SELECT_UPDATE );
	SelectPolyType( POLY_UVSHADE, TRUE, SELECT_OR );
	sel2 = Select();
	if (( ShiftStat() & 3 ) == 1 )
		Select(sel1|sel2);
	else if (( ShiftStat() & 3 ) == 2 )
		Select(sel1&sel2);
	else if (( ShiftStat() & 3 ) == 3 )
		Select(sel1^sel2);
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	マッピングされた面を非選択
//
function DeselectMap()
{
	SelectPolyType( POLY_UV, FALSE, SELECT_AND );
	SelectPolyType( POLY_UVSHADE, FALSE, SELECT_AND );
	Update( OVERWRITE );
	prevnext_flag = FALSE;
}

//
//	指定範囲を選択
//
function _SelectArea()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:選択範囲を指定】";
	DrawStatus();
	InputEvent( AreaSelect );
	KeyEvent( AreaSelect, INPUT_KEY );
}

//
//	指定範囲を非選択
//
function DeselectArea()
{
	ClearStatus();
	Status_title[0] = "【ﾓｰﾄﾞ:非選択範囲を指定】";
	DrawStatus();
	InputEvent( AreaDeselect );
	KeyEvent( AreaDeselect, INPUT_KEY );
}

//
//	選択範囲を広げる
//
function SelectWide()
{
	var	sel;

	if ( SelectPolygons() == 0 )
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg3 );
		return ;
	}
	sel = Select();
	EdgeSelect( EdgeSelect(), TRUE, SELECT_UPDATE );
	if( sel == Select() )
	{
		Warning();
		if( novice_flag == ON )
			Message( "これ以上選択範囲を広げられません" );
	}
	else
	{
		Update( OVERWRITE );
		prevnext_flag = FALSE;
	}
}

//
//	選択範囲を狭める
//
function SelectNarrow()
{
	var	edge_temp, sel;
	if ( SelectPolygons() == 0 )
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg3 );
		return ;
	}
	sel = Select();
	SelectAll( TRUE, SELECT_XOR );
	EdgeSelect( EdgeSelect(), TRUE, SELECT_UPDATE );
	SelectAll( TRUE, SELECT_XOR );
	if( sel == Select())
	{
		Warning();
		if( novice_flag == ON )
			Message( "選択範囲を狭めることができません" );
	}
	else
	{
		Update( OVERWRITE );
		prevnext_flag = FALSE;
	}
}

//
//	次の面を選択
//
function SelectNext()
{
	if ( prevnext_flag == TRUE )
	{
		if( SelectPolygons() != 0 )
		{
			if( (SelectPolygons(prevnext_sel)-1) > prevnext_selno )
				prevnext_selno = prevnext_selno + 1;
			else
				prevnext_selno = 0;
		}
	}
	else
	{
		if ( SelectPolygons() == 0 )
			SelectAll( TRUE );
		prevnext_sel = Select();
		prevnext_selno = 0;
		prevnext_flag = TRUE;
	}
	SelectNumber( prevnext_sel, prevnext_selno );
	Update( OVERWRITE );
}

//
//	前の面を選択
//
function SelectPrev()
{
	if ( prevnext_flag == TRUE )
	{
		if( prevnext_selno > 0 )
			prevnext_selno = prevnext_selno - 1;
		else
			prevnext_selno = SelectPolygons(prevnext_sel)-1;
	}
	else
	{
		if ( SelectPolygons() == 0 )
			SelectAll( TRUE );
		prevnext_sel = Select();
		prevnext_selno = SelectPolygons(prevnext_sel)-1;
		prevnext_flag = TRUE;
	}
	SelectNumber( prevnext_sel, prevnext_selno );
	Update( OVERWRITE );
}

MenuPosition(
	Menu( " 選択(&S)",
		"選択範囲を指定      	S",		_SelectArea,PolyCheck,
		"非選択範囲を指定    	D",		DeselectArea,SelectCheck,
		"--------------------",			SEPARATE_MENU,
		"選択面を反転        	N",		SelectInv,PolyFlagCheck,
		"--------------------",			SEPARATE_MENU,
		"全てを選択          	ｼﾌﾄ+S",		_SelectAll,PolyFlagCheck,
		"ｶﾚﾝﾄｱﾄﾘﾋﾞｭｰﾄを選択  	A",		_SelectAtr,PolyFlagCheck,
		"ｶﾚﾝﾄｵﾌﾞｼﾞｪｸﾄを選択  	O",		_SelectObj,PolyFlagCheck,
		"法線のある面を選択  ",			SelectShade,PolyFlagCheck,
		"ﾏｯﾋﾟﾝｸﾞ面を選択     ",			SelectMap,PolyFlagCheck,
		"--------------------",			SEPARATE_MENU,
		"全てを非選択        	ｼﾌﾄ+D",		DeselectAll,SelectCheck,
		"ｶﾚﾝﾄｱﾄﾘﾋﾞｭｰﾄを非選択",			DeselectAtr,SelectCheck,
		"ｶﾚﾝﾄｵﾌﾞｼﾞｪｸﾄを非選択",			DeselectObj,SelectCheck,
		"法線のある面を非選択",			DeselectShade,SelectCheck,
		"ﾏｯﾋﾟﾝｸﾞ面を非選択   ",			DeselectMap,SelectCheck,
		"--------------------",			SEPARATE_MENU,
		"選択範囲を広げる    	ｼﾌﾄ+R_UP",	SelectWide,SelectCheck,
		"選択範囲を狭める    	ｼﾌﾄ+R_DOWN",	SelectNarrow,SelectCheck,
		"--------------------",			SEPARATE_MENU,
		"次の面を選択        	R_UP",		SelectNext,PolyFlagCheck,
		"前の面を選択        	R_DOWN",	SelectPrev, PolyFlagCheck
	), Menu_select
);
